package comet;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;

import javax.servlet.AsyncContext;
import javax.servlet.http.HttpServletRequest;

import sun.core.json.JSONObject;
import sun.reflect.generics.tree.Tree;

import com.google.gson.Gson;
import com.sun.app.service.ServiceManager;
import com.sun.core.bean.BeanManager;

import comet.vo.Host;

public class ChatManage {
	private static ChatManage Insatance = new ChatManage();
	private static ServiceManager sermger = (ServiceManager) BeanManager
			.getBean("ServiceManager");
	// 在线列表
	private static Map<String, Host> onlineHashMap = new ConcurrentHashMap<String, Host>();
	private static BlockingQueue<Host> userQueue = new LinkedBlockingQueue<Host>();
	// 消息队列
	private static BlockingQueue<Map<String, Object>> messagesQueue = new LinkedBlockingQueue<Map<String, Object>>();
	// 系统服务队列(下线)
	private static BlockingQueue<Map<String, Object>> leaveLineQueue = new LinkedBlockingQueue<Map<String, Object>>();
	// 通知队列
	private static BlockingQueue<Map<String, Object>> sysMessageQueue = new LinkedBlockingQueue<Map<String, Object>>();
	// 在线推送线程
	private static Thread onlineListThread = new Thread(new Runnable() {
		// 如果userQueue中的Async失效、那么抛出异常
		public void run() {
			// TODO Auto-generated method stub
			/*
			 * 好友上线提醒
			 */
			while (true) {
				try {
					Host host = userQueue.take();
					List<String> friends = host.getFriends();
					Iterator<String> it = friends.iterator();
					while (it.hasNext()) {
						String hostId = it.next();
						Host fhost = onlineHashMap.get(hostId);
						if (fhost != null) {
							// 将我加入好友的在线列表
							System.out.println(onlineHashMap);
							System.out.println("将" + host + "推送给" + fhost);
							fhost.getFriends().add(host.getUserid());
							System.out.println(fhost.getFriends());
							// 把我推送给所有好友
							fhost.receive(host
									.hostToJson(StatusConst.PULL_SELF));
						}
					}
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

			}
		}
	});

	// 消息推送线程
	private static Thread messageThread = new Thread(new Runnable() {

		@SuppressWarnings("unchecked")
		@Override
		public void run() {
			// TODO Auto-generated method stub
			while (true) {
				try {
					Map<String, Object> message = messagesQueue.take();
					System.out.println("有新消息" + message);
					String toUid = (String) message.get("userid");
					Host tHost = onlineHashMap.get(toUid);
					if (tHost != null) {
						String fromId = (String) message.get("fromUserId");
						Map userMap = sermger.getUserService().getUserMap(
								fromId);
						JSONObject jo = new JSONObject();
						jo.put("status", StatusConst.CHAT_ONE);
						jo.put("fromUserId", message.get("fromUserId"));
						jo.put("fromUserName", userMap.get("USERTRUENAME"));
						jo.put("fromMsg", message.get("message"));
						jo.put("fromUserPhoto", sermger.getUserService()
								.getPhotoByUID(fromId));
						tHost.receive(jo.toString());
					}
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	});

	// 下线控制线程
	private static Thread leaveLineThread = new Thread(new Runnable() {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			while (true) {
				try {
					Map<String, Object> m = leaveLineQueue.take();
					Host host = (Host) m.get("host");
					m.remove("host");
					host.receive(new Gson().toJson(m));
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	});

	// 通知队列
	private static Thread sysMessageThread = new Thread(new Runnable() {

		@Override
		public void run() {
			// TODO Auto-generated method stub
			try {
				Map<String, Object> sysMsg = sysMessageQueue.take();
				String toId = (String) sysMsg.get("toId");
				Host host = onlineHashMap.get(toId);
				host.receive(new Gson().toJson(sysMsg));
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	});

	private ChatManage() {
	}

	public static ChatManage getInstance() {
		return Insatance;
	}

	/*
	 * 监控线程启动
	 */
	public void startOnlineThread() {
		onlineListThread.start();
	}

	public void startSysMessageTread() {
		leaveLineThread.start();
	}

	public void startMsgThread() {
		messageThread.start();
	}

	/*
	 * 将用户加入online列表中
	 */
	public void addUser(Host h) {
		// 因为刷新导致Async失效
		// if(!onlineHashMap.containsKey(h.getUserid())){
		// List<String> friends = h.getFriends();
		// for(Host t : friends.values()){
		// t.getFriends().put(h.getUserid(), h);
		// }
		// }
		onlineHashMap.put(h.getUserid(), h);
		refreshOnlineStatus(true, h.getUserid());
	}

	/*
	 * 将用户添加到列表
	 */
	public void pullUser(Host h) {
		if (!onlineHashMap.containsKey(h.getUserid())) {
			// 将用户加入推送队列
			addUserIntoQueue(h);
		}
	}

	/*
	 * 判断用户是否存在
	 */
	public boolean isOnline(String id) {
		return onlineHashMap.containsKey(id);
	}

	/*
	 * 将用户加入推送队列
	 */
	public void addUserIntoQueue(Host h) {
		userQueue.add(h);
	}

	/*
	 * 将用户下线消息加入下线队列
	 */
	public void pullLeaveLine(Map<String, Object> m) {
		leaveLineQueue.add(m);
	}

	/*
	 * 将系统消息加入到消息队列
	 */
	public void pullSysMessage(String toId, String msg) {
		Map<String, Object> m = new HashMap<String, Object>();
		m.put("toId", toId);
		m.put("msg", msg);
		m.put("status", StatusConst.SYSTEM_MESSAGE);
		sysMessageQueue.add(m);
	}

	/*
	 * 将信息加入消息队列
	 */
	public void pullMessage(Map<String, Object> m) {
		messagesQueue.add(m);
	}

	/*
	 * 获取当前Post方法访问的Async对象
	 */
	public AsyncContext getCurrentAsync(HttpServletRequest req) {
		System.out.println(req.getParameter("metadata.id"));
		Host host = onlineHashMap.get(req.getParameter("metadata.id"));
		return host.getAsync();
	}

	/*
	 * 将在线好友信息推送至自己
	 */
	public void pullAllOnlineFriends(Host h) {
		List<String> friends = h.getFriends();
		List<Map<String, Object>> l = new ArrayList<Map<String, Object>>();
		Iterator<String> it = friends.iterator();
		System.out.println("+++++++++++++++++++++++++++++++++++++++\n"
				+ friends);
		while (it.hasNext()) {
			String hostId = it.next();
			Host f = onlineHashMap.get(hostId);
			if (f == null) {
				continue;
			}
			Map<String, Object> m = new HashMap<String, Object>();
			m.put("UID", f.getUserid());
			m.put("USERNAME", f.getUsername());
			m.put("photo", f.getPhoto());
			l.add(m);
		}
		Map<String, Object> t = new HashMap<String, Object>();
		t.put("friends", l);
		t.put("totalCount", l.size());
		t.put("status", StatusConst.REFRESH_LIST);
		h.receive(new Gson().toJson(t));
	}

	/*
	 * 获取好友列表
	 */
	public List<String> getFriendsList(Host h) {
		List<Map<String, Object>> onlineFriendList = sermger.getFriendService()
				.getOnlineFriendList(h.getUserid());
		Iterator<Map<String, Object>> it = onlineFriendList.iterator();
		List<String> l = new ArrayList<String>();
		while (it.hasNext()) {
			Map<String, Object> next = it.next();
			l.add((String) next.get("UID"));
		}
		return l;
	}

	/*
	 * 更新在线状态
	 */
	public void refreshOnlineStatus(boolean online, String UID) {
		sermger.getFriendService().refreshOnlineStatus(online, UID);
	}

	/*
	 * 将用户从在线队列中删除
	 */
	public void removeHost(String id) {
		// TODO Auto-generated method stub
		Host host = onlineHashMap.get(id);
		List<String> friends = host.getFriends();
		Iterator<String> it = friends.iterator();
		while (it.hasNext()) {
			String hostId = it.next();
			System.out.println(onlineHashMap);
			System.out.println("操你妹" + hostId);
			Host h = onlineHashMap.get(hostId);
			System.out.println("!!!!!!!!!!!!!!!!!!!" + h.getFriends());
			h.getFriends().remove(id);
			Map<String, Object> m = new HashMap<String, Object>();
			m.put("leaveId", id);
			m.put("host", h);
			m.put("status", StatusConst.PEOPLE_LEAVE);
			pullLeaveLine(m);
		}
		System.out.println(host.getUsername() + "下线了");
		refreshOnlineStatus(false, id);
		onlineHashMap.remove(id);
	}

}
